package com.anivia.common.web.config.desensitization;

import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import com.anivia.common.core.enums.DesensitizedTypeEnum;
import com.anivia.common.web.model.vo.DesensitizedVO;
import com.anivia.common.web.privoder.DataHandlerProvider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;

import java.util.Set;

/**
 * 数据脱敏权限上下文
 *
 * @author wangj
 */

@Slf4j
public class DataDesensitizationContext {
    private static final ThreadLocal<DesensitizedVO> DATA_SCOPE = new InheritableThreadLocal<>();

    /**
     * 开启自定义范围数据脱敏权限功能
     *
     * @param customRange 要脱敏的字段
     */
    public static void startCustom(Set<DesensitizedTypeEnum> customRange) {
        start(true, customRange);
    }

    /**
     * 开启数据权限配置的脱敏权限功能
     */
    public static void start() {
        start(false, null);
    }

    /**
     * 开启数据脱敏权限功能
     *
     * @param useCustom 是否使用自定义的脱敏范围
     * @param list      需要脱敏字段
     */
    private static void start(Boolean useCustom, Set<DesensitizedTypeEnum> list) {
        DesensitizedVO vo = new DesensitizedVO();
        vo.setOpenDesensitization(true);
        if (useCustom) {
            vo.setDescensitizationList(list);
        } else {
            DataHandlerProvider provider = null;
            try {
                provider = SpringUtil.getBean(DataHandlerProvider.class);
            } catch (NoSuchBeanDefinitionException e) {
                throw new RuntimeException("当前服务未实现DataHandlerProvider，数据脱敏权限功能无法使用。");
            }
            // 通过业务查询要脱敏的字段
            Set<DesensitizedTypeEnum> typeList = provider.getDescensitizationListByLoginUser();
            log.info("当前业务需要脱敏的字段为：{}", JSONUtil.toJsonStr(typeList));
            vo.setDescensitizationList(typeList);
        }
        DATA_SCOPE.set(vo);
    }

    /**
     * 查询配置
     */
    public static DesensitizedVO get() {
        if (DATA_SCOPE.get() == null) {
            // 默认关闭
            DesensitizedVO vo = new DesensitizedVO();
            vo.setOpenDesensitization(false);
            return vo;
        }
        return DATA_SCOPE.get();
    }
}